/**
 *
 */
package org.linlinjava.litemall.db.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.FastDateFormat;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

@Slf4j
public class DateTimeUtils {

    public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_FORMAT = "yyyy-MM-dd";

    public static final String DATE_TIME_FORMAT_HH = "yyyy-MM-dd-HH";

    public static final String SDF = "yyyyMMdd";

    public static final String DATE_TIME = "yyyy-MM-ddHHmmss";

    private static Date ZERO_TIME = null;

    static {
        Calendar cal = Calendar.getInstance();
        cal.setTimeInMillis(0);
        ZERO_TIME = cal.getTime();
    }

    public static Date getZeroTime(){
        return ZERO_TIME;
    }

    public static Date parseNormalDateStr(String str){
        Date rst = null;
        FastDateFormat fdf = FastDateFormat.getInstance(DATE_FORMAT);
        try {
            rst = fdf.parse(str);
        } catch (ParseException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return rst;
    }

    public static Date parseDate(String str, String format){
        Date rst = null;
        FastDateFormat fdf = FastDateFormat.getInstance(format);
        try {
            rst = fdf.parse(str);
        } catch (ParseException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return rst;
    }

    public static String format(Date date, String format) {
        FastDateFormat fdf = FastDateFormat.getInstance(format);
        return fdf.format(date);
    }

    public static String formatDate(Date date, String format){
        FastDateFormat fdf = FastDateFormat.getInstance(format);
        return fdf.format(date);
    }

    public static String formatDateStr(Date date){
        FastDateFormat fdf = FastDateFormat.getInstance(DATE_FORMAT);
        return fdf.format(date);
    }

    public static Date parseNormalDateTimeStr(String str){
        Date rst = null;
        try {
            FastDateFormat fdf = FastDateFormat.getInstance(DATE_TIME_FORMAT);
            rst = fdf.parse(str);
        } catch (ParseException e) {
            log.error(ExceptionUtils.getStackTrace(e));
        }
        return rst;
    }

    public static String formatDateTimeStr(Date date){
        FastDateFormat fdf = FastDateFormat.getInstance(DATE_TIME_FORMAT);
        return fdf.format(date);
    }


    /**
     * 若干小时后的时间
     * @param date
     * @param hours
     * @return
     */
    public static Date addHours(Date date, int hours) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.HOUR, hours);
        date = (Date) c.getTime();
        return date;
    }

    /**
     * 几分钟后的时间
     * @param minute
     * @return
     */
    public static Date addminute(Date date, int minute) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MINUTE, minute);
        date = (Date) c.getTime();
        return date;
    }

    /**
     * 得到当前时间增加若干天的时间
     * @param date
     * @param days
     * @return
     */
    public static Date addDays(Date date, int days) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, days);
        date = (Date) c.getTime();
        return date;
    }


    /**
     * ����ַ��ʽ���ڣ�����Date
     * @param d Date
     * @return ��ǰ��ϵͳ����
     */
    public static Date getDate(String d) {
        Timestamp ts = Timestamp.valueOf(d);
        return ts;
    }


    /**
     * 得到指定时间所在那一天的开始时间
     * @param date
     * @return
     */
    public static Date beginOfDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);
        date = (Date) c.getTime();
        return date;
    }

    /**
     * 得到指定时间所在那一天的结束时间
     * @param date
     * @return
     */
    public static Date endOfDay(Date date) {
        Calendar c = Calendar.getInstance();
        System.out.println(date);
        c.setTime(date);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
//        c.set(Calendar.MILLISECOND, 999);
        date = (Date) c.getTime();
        return date;
//        date = beginOfDay(date);
//        return endOfDayByBeginOfDate(date);
    }



    /**
     * 指定日期过去若干天的日期,例如得到从2013年1月1日开始10天后的时间
     * by Yin Jian
     *
     * @param date 指定的日期
     * @param days 天数
     * @return 若干天后的日期
     */
    public static Date afterDaysSinceDate(Date date, int days) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, days);
        date = (Date) c.getTime();
        return date;
    }


    /**
     * 得到指定时间的一下天的开始时间
     *
     * @param date ָ��Date
     * @return ��һ��Ŀ�ʼʱ��
     */
    public static Date beginOfNextDay(Date date) {
        date = nextDay(date);
        return beginOfDay(date);
    }

    /**
     * 得到与当前时间相同的下一天的时间
     *
     * @param date ����
     * @return �������ڵ���һ��
     */
    public static Date nextDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, 1);
        date = (Date) c.getTime();
        return date;
    }

    /**
     * 得到前一天的时间
     *
     * @param date ����
     * @return �������ڵ�ǰһ��
     */
    public static Date preDay(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, -1);
        date = (Date) c.getTime();
        return date;
    }


    public static Date addDate(Date date, int num) {
        return new Date(date.getTime() + num * (long) 24 * 3600 * 1000);
    }

    public static Date getYesterday(){
        return DateUtils.addDays(new Date(), -1);
    }

    /**
     * 返回指定日期所在当月的第一天的日期
     * @param date
     * @return
     */
    public static Date firstDay(Date date) {
        Calendar calendar = convert(date);
        calendar.set(Calendar.DATE, 1);
        return calendar.getTime();
    }

    /**
     * 返回指定日期所在当月的最后一天的日期
     * @param date
     * @return
     */
    public static Date lastDay(Date date) {
        Calendar calendar = convert(date);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        return calendar.getTime();
    }

    private static Calendar convert(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return calendar;
    }



    private static final long ONE_MINUTE = 60;
    private static final long ONE_HOUR = 3600;
    private static final long ONE_DAY = 86400;
    private static final long ONE_MONTH = 2592000;
    private static final long ONE_YEAR = 31104000;

    /**
     * 距离截止日期还有多长时间
     *
     * @param date
     * @return
     */
    public static String fromDeadline(Date date) {
        long deadline = date.getTime() / 1000;
        long now = (new Date().getTime()) / 1000;
        long remain = deadline - now;
        if (remain <= ONE_HOUR)
            return "只剩下" + remain / ONE_MINUTE + "分钟";
        else if (remain <= ONE_DAY)
            return "只剩下" + remain / ONE_HOUR + "小时"
                    + (remain % ONE_HOUR / ONE_MINUTE) + "分钟";
        else {
            long day = remain / ONE_DAY;
            long hour = remain % ONE_DAY / ONE_HOUR;
            long minute = remain % ONE_DAY % ONE_HOUR / ONE_MINUTE;
            return "只剩下" + day + "天" + hour + "小时" + minute + "分钟";
        }

    }
}
